﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Xml;
using System.Xml.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Media;

namespace SpriteSheetsCreator {
    public class MainViewModel : INotifyPropertyChanged {
        #region Constants
        public const int NB_DISPLAY_BEFORE_RATING_MESSAGE = 10;
        #endregion

        #region Attributes
        public ObservableCollection<ImageViewModel> ImagesList { get; private set; }
        #endregion

        #region Constructors
        public MainViewModel() {
            this.ImagesList = new ObservableCollection<ImageViewModel>();
            GuiAnimationSpeed = 33;
        }
        #endregion

        #region Properties
        private string _sampleProperty = "Sample Runtime Property Value";
        /// <summary>
        /// Sample ViewModel property; this property is used in the view to display its value using a Binding
        /// </summary>
        /// <returns></returns>
        public string SampleProperty {
            get {
                return _sampleProperty;
            }
            set {
                if (value != _sampleProperty) {
                    _sampleProperty = value;
                    NotifyPropertyChanged("SampleProperty");
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        private int _guiAnimationSpeed;
        public int GuiAnimationSpeed {
            get {
                return _guiAnimationSpeed;
            }
            set {
                if (value != _guiAnimationSpeed) {
                    _guiAnimationSpeed = value;
                    GuiAnimationSpeedStr = value.ToString();
                    NotifyPropertyChanged("GuiAnimationSpeed");
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        private string _guiAnimationSpeedStr;
        public string GuiAnimationSpeedStr {
            get {
                return _guiAnimationSpeedStr;
            }
            set {
                if (value != _guiAnimationSpeedStr) {
                    _guiAnimationSpeedStr = value;
                    GuiAnimationSpeed = value.toInteger(33);
                    NotifyPropertyChanged("GuiAnimationSpeedStr");
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        private bool _autoreverseAnim;
        public bool AutoreverseAnim {
            get {
                return _autoreverseAnim;
            }
            set {
                if (value != _autoreverseAnim) {
                    _autoreverseAnim = value;
                    NotifyPropertyChanged("AutoreverseAnim");
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        private Stretch _previewStretchStyle;
        public Stretch PreviewStretchStyle {
            get {
                return _previewStretchStyle;
            }
            set {
                if (value != _previewStretchStyle) {
                    _previewStretchStyle = value;
                    NotifyPropertyChanged("PreviewStretchStyle");
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public string PreviewStretchStyleStr {
            get { return PreviewStretchStyle.ToString(); }
            set { PreviewStretchStyle = (Stretch)Enum.Parse(typeof(Stretch), value.subRemoveLeft(value.LastIndexOf(": ") + 2), true); }
        }

        /// <summary>
        /// If true: Result sprite sheet will have fixed width/height sprites (if source images dimension are not equal, get max width/height) - result will get a width of max sprite width x nb sprites
        /// Is false: Result sprite sheet will have all sprites one after another, each with their original width/height
        /// </summary>
        /// <returns></returns>
        private bool _fixedSpriteSize;
        public bool FixedSpriteSize {
            get {
                return _fixedSpriteSize;
            }
            set {
                if (value != _fixedSpriteSize) {
                    _fixedSpriteSize = value;
                    NotifyPropertyChanged("FixedSpriteSize");
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        private bool _resizeForOutput;
        public bool ResizeForOutput {
            get {
                return _resizeForOutput;
            }
            set {
                if (value != _resizeForOutput) {
                    _resizeForOutput = value;
                    NotifyPropertyChanged("ResizeForOutput");
                }
            }
        }

        /// <summary>
        /// Used only if ResizeForOutput is set to true.
        /// Resize sprites to this max width before rendering if larger
        /// </summary>
        /// <returns></returns>
        private int _maxPixelWidth;
        public int MaxPixelWidth {
            get {
                return _maxPixelWidth;
            }
            set {
                if (value != _maxPixelWidth) {
                    _maxPixelWidth = value;
                    NotifyPropertyChanged("MaxPixelWidth");
                }
            }
        }

        /// <summary>
        /// Used only if ResizeForOutput is set to true.
        /// Resize sprites to this max height before rendering if larger
        /// </summary>
        /// <returns></returns>
        private int _maxPixelHeight;
        public int MaxPixelHeight {
            get {
                return _maxPixelHeight;
            }
            set {
                if (value != _maxPixelHeight) {
                    _maxPixelHeight = value;
                    NotifyPropertyChanged("MaxPixelHeight");
                }
            }
        }
        #endregion

        #region Property events (used for PropertyChanged behavior)
        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged(String propertyName) {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (null != handler) {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        #endregion
    }
}